package com.leizi.igym.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.leizi.igym.constant.CourseConstant;
import com.leizi.igym.domain.Course;
import com.leizi.igym.domain.Trainer;
import com.leizi.igym.dto.CourseAddDTO;
import com.leizi.igym.dto.CourseDTO;
import com.leizi.igym.dto.CoursePageQueryDTO;
import com.leizi.igym.enums.ReturnCodeEnum;
import com.leizi.igym.exception.BusinessException;
import com.leizi.igym.service.CategoryService;
import com.leizi.igym.service.CourseService;
import com.leizi.igym.mapper.CourseMapper;
import com.leizi.igym.service.TrainerService;
import com.leizi.igym.utils.DateQWUtils;
import com.leizi.igym.utils.ThrowUtils;
import com.leizi.igym.vo.CourseGoodsVO;
import com.leizi.igym.vo.CourseVO;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

/**
 * @author PC
 * @description 针对表【t_course(课程表)】的数据库操作Service实现
 * @createDate 2024-04-18 16:09:16
 */
@Service
public class CourseServiceImpl extends ServiceImpl<CourseMapper, Course>
        implements CourseService {

    @Resource
    private CourseMapper courseMapper;

    @Resource
    private CategoryService categoryService;

    @Resource
    private TrainerService trainerService;

    /**
     * 在管理端新增课程
     *
     * @param dto
     * @return: boolean
     **/
    @Override
    @Transactional
    public boolean saveInAdmin(CourseAddDTO dto) {
        if (Objects.isNull(dto)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }

        String courseName = dto.getCourseName();
        String cover = dto.getCover();
        Integer lessonNum = dto.getLessonNum();
        Long trainerId = dto.getTrainerId();
        BigDecimal price = dto.getPrice();
        Long categoryId = dto.getCategoryId();
        String descrip = dto.getDescrip();


        List<Long> allId = categoryService.getAllId();
        if (CollectionUtil.isEmpty(allId)) {
            throw new BusinessException(ReturnCodeEnum.SYSTEM_ERROR, "无分类消息");
        }

        // 判断参数合法性
        if (StringUtils.isAnyBlank(courseName, cover,descrip)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }

        if (!allId.contains(categoryId)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }

        if (Objects.isNull(lessonNum) || lessonNum < 0) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }

        if (Objects.isNull(trainerId) || trainerId < 0) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }

        if (Objects.isNull(price) || price.compareTo(BigDecimal.ZERO) < 0) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }

        Trainer dbTrainer = trainerService.getById(trainerId);

        if (Objects.isNull(dbTrainer)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR, "教授该课教练信息不存在！");
        }

        // 构造插入对象
        Course course = new Course();
        BeanUtils.copyProperties(dto, course);
        // 默认管理端添加是已认证了
        Integer result = this.getBaseMapper().insert(course);
        return null != result && result >= 1;
    }

    /**
     * 管理端删除课程
     *
     * @param id
     * @return: boolean
     **/
    @Override
    public boolean deleteTrainerInAdmin(Long id) {
        ThrowUtils.throwIf(Objects.isNull(id) || id <= 0, ReturnCodeEnum.PARAMS_ERROR);
        // 删除课程
        Integer result = this.getBaseMapper().deleteById(id);
        return null != result && result >= 1;
    }

    /**
     * 批量删除课程
     *
     * @param ids
     * @return: boolean
     **/
    @Override
    public boolean deleteTrainerBatchInAdmin(List<Long> ids) {
        ThrowUtils.throwIf(CollectionUtil.isEmpty(ids), ReturnCodeEnum.PARAMS_ERROR);
        Integer result = this.getBaseMapper().deleteBatchIds(ids);
        return null != result && result >= 1;
    }

    /**
     * 修改课程
     *
     * @param dto
     * @return: boolean
     **/
    @Override
    public boolean updateInAdmin(CourseDTO dto) {
        ThrowUtils.throwIf(Objects.isNull(dto), ReturnCodeEnum.PARAMS_ERROR);
        Trainer dbTrainer = trainerService.getById(dto.getTrainerId());
        if (Objects.isNull(dbTrainer)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR, "教授改课教练信息不存在！");
        }
        Course course = new Course();
        BeanUtils.copyProperties(dto, course);
        // 更课程练信息
        Integer result = this.getBaseMapper().updateById(course);
        return null != result && result >= 1;
    }

    /**
     * 根据id查询课程信息
     *
     * @param id
     * @return: com.leizi.igym.vo.CourseVO
     **/
    @Override
    public CourseVO getVOById(Long id) {
        ThrowUtils.throwIf(Objects.isNull(id) || id <= 0,
                ReturnCodeEnum.PARAMS_ERROR);
        CourseVO courseVO = courseMapper.selectVOById(id);
        return courseVO;
    }


    @Override
    public QueryWrapper<Course> getPageQueryWrapper(CoursePageQueryDTO dto) {
        if (Objects.isNull(dto)) {
            return null;
        }

        Long id = dto.getId();
        Long categoryId = dto.getCategoryId();
        String courseName = dto.getCourseName();
        Integer status = dto.getStatus();
        Long trainerId = dto.getTrainerId();
        LocalDate beginTime = dto.getBeginTime();
        LocalDate endTime = dto.getEndTime();

        if (!DateQWUtils.dateCompare(beginTime, endTime)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR, "传入地日期有误！");
        }

        QueryWrapper<Course> qw = new QueryWrapper<>();
        qw.like(Objects.nonNull(id), "id", id);
        qw.eq(Objects.nonNull(categoryId), "category_id", categoryId);
        qw.eq(Objects.nonNull(status), "status", status);
        qw.eq(Objects.nonNull(trainerId), "trainer_id", trainerId);
        qw.eq(StringUtils.isNotBlank(courseName), "course_name", courseName);
        qw.ge(Objects.nonNull(beginTime), "publish_time", beginTime);
        qw.le(Objects.nonNull(endTime), "publish_time", endTime);
        qw.eq("tco.deleted",0);

        return qw;

    }

    /**
     * 分页查询课程
     *
     * @param dto
     * @return: Page<com.leizi.igym.vo.CourseVO>
     **/
    @Override
    public Page<CourseVO> getVOPage(CoursePageQueryDTO dto) {
        return this.getBaseMapper().selectVOPage(new Page<>(dto.getCurrent(), dto.getPageSize())
                , this.getPageQueryWrapper(dto));
    }

    /**
     * 修改课程发布状态
     *
     * @param id
     * @param status
     * @return: boolean
     **/
    @Override
    public boolean changeStatus(Long id, Integer status) {
        // 校验参数id是否合法
        ThrowUtils.throwIf(Objects.isNull(id) || id < 0, ReturnCodeEnum.PARAMS_ERROR);
        // 校验status参数是否合法
        ThrowUtils.throwIf(Objects.isNull(status) ||
                !CourseConstant.COURSE_STATUS_LIST.contains(status)
                , ReturnCodeEnum.PARAMS_ERROR);

        Course dbCourse = this.getBaseMapper().selectById(id);
        ThrowUtils.throwIf(Objects.isNull(dbCourse), ReturnCodeEnum.PARAMS_ERROR);
        dbCourse.setStatus(status);
        if (status.equals(CourseConstant.NOT_PUBLISH)){
            dbCourse.setPublishTime(null);
        }
        dbCourse.setPublishTime(LocalDateTime.now());
        return this.getBaseMapper().updateById(dbCourse) > 0;
    }

    @Override
    public Page<CourseGoodsVO> getCourseGoodsVOPage(CoursePageQueryDTO dto) {
        if (Objects.isNull(dto)) {
            throw new BusinessException(ReturnCodeEnum.PARAMS_ERROR);
        }
        QueryWrapper<Course> qw = new QueryWrapper<>();
        qw.eq("deleted",0);
        qw.eq("status",CourseConstant.PUBLISHED);
        qw.like(StringUtils.isNotBlank(dto.getCourseName()),"course_name",dto.getCourseName());
        Page<CourseGoodsVO> page =
                this.getBaseMapper().selectCourseGoodsList(new Page<CourseGoodsVO>(dto.getCurrent(),
                        dto.getPageSize()), qw);
        return page;
    }
}




